package ar.edu.uba.fi.jmit.monitorengine.core.monitor;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import ar.edu.uba.fi.jmit.integrationcommons.Event;
import ar.edu.uba.fi.jmit.integrationcommons.EventPriority;
import ar.edu.uba.fi.jmit.monitorengine.Constants;
import ar.edu.uba.fi.jmit.monitorengine.MonitorEngineTestCase;
import ar.edu.uba.fi.jmit.monitorengine.ResourceProperties;
import ar.edu.uba.fi.jmit.monitorengine.exception.ConfigurationException;
import ar.edu.uba.fi.jmit.monitorengine.exception.MonitorEngineException;
import ar.edu.uba.fi.jmit.monitorengine.mock.ConfigurationManagerMock;
import ar.edu.uba.fi.jmit.monitorengine.mock.EventCounterMonitorMock;
import ar.edu.uba.fi.jmit.monitorengine.mock.MonitorEngineSenderMock;

public class AbstractEventCounterMonitorTestCase extends MonitorEngineTestCase {
	
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		ConfigurationManagerMock.useMockConfigurationManager();
	}

	public void testInit() {
		EventCounterMonitorMock monitor = new EventCounterMonitorMock();
		monitor.setMonitorEngineSender(new MonitorEngineSenderMock());
		Map<String, String> configuration = new HashMap<String, String>();
		try {
			monitor.init(configuration);
		} catch (ConfigurationException e) {
			fail(e);
		}
		monitor.destroy();
		configuration = new HashMap<String, String>();
		configuration.put("eventPeriod.value", "15");
		try {
			monitor.init(configuration);
		} catch (ConfigurationException e) {
			fail(e);
		}
		monitor.destroy();
		
		configuration = new HashMap<String, String>();
		configuration.put("eventPeriod.value", "b");
		try {
			monitor.init(configuration);
			fail("Exception should be thrown!");
		} catch (ConfigurationException e) {
			//expected
		}
		monitor.destroy();
		
		configuration = new HashMap<String, String>();
		configuration.put("eventPeriod.value", "");
		try {
			monitor.init(configuration);
			fail("Exception should be thrown!");
		} catch (ConfigurationException e) {
			//expected
		}
		monitor.destroy();
		
		configuration = new HashMap<String, String>();
		configuration.put("eventPeriod.value", "15");
		configuration.put("timeInterval.value", "10");
		try {
			monitor.init(configuration);
		} catch (ConfigurationException e) {
			fail(e);
		}
		monitor.destroy();
		
		configuration = new HashMap<String, String>();
		configuration.put("eventPeriod.value", "15");
		configuration.put("timeInterval.value", "10b");
		try {
			monitor.init(configuration);
			fail("Exception should be thrown!");
		} catch (ConfigurationException e) {
			//expected
		}
		monitor.destroy();
	}
	
	public void testExecute() throws InterruptedException, MonitorEngineException {
		EventCounterMonitorMock monitor = new EventCounterMonitorMock();
		Map<String, String> configuration = new HashMap<String, String>();
		configuration.put("eventPeriod.value", "1");
		configuration.put("timeInterval.value", "15");
		try {
			monitor.init(configuration);
		} catch (ConfigurationException e) {
			fail(e);
		}
		Event event = this.createEvent();
		monitor.doExecute(event);
		Thread.sleep(100);
		assertEquals(1, monitor.getSendedEventCount());
		Thread.sleep(1005);
		assertEquals(2, monitor.getSendedEventCount());

		for(int i = 0; i < 19; i++) {
			event = this.createEvent();
			monitor.doExecute(event);
		}
		
		Thread.sleep(1005);
		assertEquals(3, monitor.getSendedEventCount());
		monitor.destroy();
	}
	
	private Event createEvent() {
		return createEvent(new Date());
	}
	
	private Event createEvent(Date eventDate) {
		Event event = new Event();
		event.setSource("createEvent");
		event.setPriority(EventPriority.NORMAL);
		event.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "test1");
		event.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE), eventDate);
		return event;
	}
}
